{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# C++的内建函数对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. 内建函数对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "① STL内建来了一些函数对象：\n",
    "\n",
    "1. 算术仿函数\n",
    "2. 关系仿函数\n",
    "3. 逻辑仿函数\n",
    "\n",
    "② 用法：\n",
    "\n",
    "1. 这些仿函数所产生的对象，用法和一般函数完全相同。\n",
    "2. 使用内建函数对象，需要引入头文件 #include<functional>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 算术仿函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "① 功能描述：实现四则运算。\n",
    "\n",
    "② 其中negate是一元运算，其他都是二元运算。\n",
    "\n",
    "③ 仿函数原型：\n",
    "\n",
    "1. $template<class T> T plus<T>$ //加法仿函数\n",
    "2. $template<class T> T minus<T>$ //减法仿函数\n",
    "3. $template<class T> T multiplies<T>$ //乘法仿函数\n",
    "4. $template<class T> T divides<T>$ //除法仿函数\n",
    "5. $template<class T> T modulus<T>$ //取模仿函数\n",
    "6. $template<class T> T negate<T>$ //取反仿函数\n",
    "\n",
    "④ 使用内建函数对象时，需要引入头文件#include <functional>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include<iostream>\n",
    "using namespace std;\n",
    "#include<functional>  //内建函数对象头文件\n",
    "\n",
    "//内建函数对象 算术仿函数\n",
    "\n",
    "//negate 一元仿函数 取反仿函数\n",
    "void test01()\n",
    "{\n",
    "    negate<int>n;\n",
    "\n",
    "    cout << n(50) << endl;\n",
    "}\n",
    "\n",
    "//plus 二元仿函数  加法\n",
    "void test02()\n",
    "{\n",
    "    plus<int>p;  //写一个int就好了，不用写两个int，它默认是两个同类型的int相加\n",
    "\n",
    "    cout << p(50,60) << endl;\n",
    "}\n",
    "\n",
    "int main() {\n",
    "\n",
    "    test01();\n",
    "    test02();\n",
    "\n",
    "    system(\"pause\");\n",
    "\n",
    "    return 0;\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运行结果：\n",
    " - -50\n",
    " - 110\n",
    " - 请按任意键继续. . ."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 关系仿函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "① 功能描述：实现关系对比。\n",
    "\n",
    "② 仿函数原型：  \n",
    "\n",
    "1. $template<class T> bool equal_to<T>$ //等于\n",
    "2. $template<class T> bool notequal_to<T>$ //不等于\n",
    "3. $template<>class T> bool greater<T>$ //大于\n",
    "4. $template<class T> bool greater_qual<T>$ //大于等于\n",
    "5. $template<class T> bool less<T>$ //小于\n",
    "6. $template<class T>bool less_equal<T>$ //小于等于  \n",
    "\n",
    "③ 关系仿函数中最常用的就是greater<>大于。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include<iostream>\n",
    "using namespace std;\n",
    "#include<functional>  //内建函数对象头文件\n",
    "#include<vector>\n",
    "#include<algorithm>\n",
    "\n",
    "\n",
    "//内建函数对象 关系仿函数\n",
    "//大于 greater\n",
    "class MyCompare\n",
    "{\n",
    "    bool operator()(int v1, int v2)\n",
    "    {\n",
    "        return v1 > v2;\n",
    "    }\n",
    "};\n",
    "\n",
    "void test01()\n",
    "{\n",
    "    vector<int>v;\n",
    "\n",
    "    v.push_back(10);\n",
    "    v.push_back(20);\n",
    "    v.push_back(30);\n",
    "    v.push_back(40);\n",
    "    v.push_back(50);\n",
    "\n",
    "    for (vector<int>::iterator it = v.begin();it!=v.end();it++)\n",
    "    {\n",
    "        cout << *it << \" \";\n",
    "    }\n",
    "    cout << endl;\n",
    "\n",
    "    //降序\n",
    "    \n",
    "    //方式一：\n",
    "    //sort(v.begin(), v.end(), MyCompare());\n",
    "    \n",
    "    //方式二：\n",
    "    sort(v.begin(), v.end(), greater<int>()); //greater<int>()为编译器给提供的函数对象，为内建的函数对象\n",
    "\n",
    "    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)\n",
    "    {\n",
    "        cout << *it << \" \";\n",
    "    }\n",
    "    cout << endl;\n",
    "}\n",
    "\n",
    "int main() {\n",
    "\n",
    "    test01();\n",
    "\n",
    "    system(\"pause\");\n",
    "\n",
    "    return 0;\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运行结果：\n",
    " - 10 20 30 40 50\n",
    " - 50 40 30 20 10\n",
    " - 请按任意键继续. . ."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 逻辑仿函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "① 功能描述：实现关系对比\n",
    "\n",
    "② 仿函数原型：\n",
    "\n",
    "1. $template<class T> bool logical_and<T>$ //逻辑与\n",
    "2. $template<class T> bool logical_or<T>$ //逻辑或\n",
    "3. $template<class T> bool logical_not<T>$ //逻辑非\n",
    "\n",
    "③ 逻辑仿函数实际应用较少，了解即可。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include<iostream>\n",
    "using namespace std;\n",
    "#include<functional>  //内建函数对象头文件\n",
    "#include<vector>\n",
    "#include<algorithm>\n",
    "\n",
    "\n",
    "//内建函数对象 逻辑仿函数\n",
    "//逻辑非 logical_not\n",
    "\n",
    "void test01()\n",
    "{\n",
    "    vector<bool>v;\n",
    "\n",
    "    v.push_back(true);\n",
    "    v.push_back(false);\n",
    "    v.push_back(true);\n",
    "    v.push_back(true);\n",
    "    v.push_back(false);\n",
    "\n",
    "    for (vector<bool>::iterator it = v.begin();it!=v.end();it++)\n",
    "    {\n",
    "        cout << *it << \" \";\n",
    "    }\n",
    "    cout << endl;\n",
    "\n",
    "    //利用逻辑非 将容器v  搬运到 容器v2中，并执行取反操作\n",
    "    vector<bool>v2;\n",
    "    v2.resize(v.size()); //目标容器要提前开辟一个空间\n",
    "\n",
    "    transform(v.begin(),v.end(),v2.begin(),logical_not<bool>()); //第一个参数：原容器起始迭代器，第二个参数：原容器终止迭代器，第三个参数：目标容器起始迭代器\n",
    "\n",
    "    for (vector<bool>::iterator it = v2.begin(); it != v2.end(); it++)\n",
    "    {\n",
    "        cout << *it << \" \";\n",
    "    }\n",
    "    cout << endl;\n",
    "}\n",
    "\n",
    "\n",
    "\n",
    "int main() {\n",
    "\n",
    "    test01();\n",
    "\n",
    "    system(\"pause\");\n",
    "\n",
    "    return 0;\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运行结果：\n",
    " - 1 0 1 1 0\n",
    " - 0 1 0 0 1\n",
    " - 请按任意键继续. . ."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.6.3",
   "language": "python",
   "name": "python3.6.3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
